/*
 * Copyright (c) 2007 jNetX.
 * http://www.jnetx.com
 * All rights reserved.
 *
 * This software is the confidential and proprietary information of
 * jNetX. You shall not disclose such Confidential Information and
 * shall use it only in accordance with the terms of the license
 * agreement you entered into with jNetX.
 *
 * $Id$
 */
package com.jnetx.javax.sip.header;

import javax.sip.header.RSeqHeader;
import javax.sip.InvalidArgumentException;

/**
 * This interface represents the RSeq header, as defined by
 * <a href = "http://www.ietf.org/rfc/rfc3262.txt">RFC3262</a>, this
 * header is not part of RFC3261.
 * <p>
 * The RSeq header is used in provisional responses in order to transmit them
 * reliably. It contains a single numeric value from 1 to 2**32-1. The value of
 * the RSeq in each subsequent reliable provisional response for the same request
 * MUST be greater by exactly one. RSeq numbers MUST NOT wrap around. Because
 * the initial one is chosen to be less than 2**31 - 1, but the maximum is
 * 2**32 - 1, there can be up to 2**31 reliable provisional responses per
 * request, which is more than sufficient. As the RSeq numbering space is within
 * a single transaction. This means that provisional responses for different
 * requests MAY use the same values for the RSeq number.
 * <p>
 * A server must ignore Headers that it does not understand. A proxy must not
 * remove or modify Headers that it does not understand.
 *
 * @author <a href="mailto:dparhonin@jnetx.ru">Dmitry Parhonin</a>
 * @version $Revision$
 */
public class RSeqHeaderImpl extends HeaderBase implements RSeqHeader {
    private static final RSeqHeaderParser parser = new RSeqHeaderParser();

    private int sequenceNumber;

    public RSeqHeaderImpl() {
        super(RSeqHeader.NAME);
    }

    RSeqHeaderImpl(byte[] data, int start, int end) {
        super(RSeqHeader.NAME, data, start, end);
    }

    public Object clone() {
        final RSeqHeaderImpl header = new RSeqHeaderImpl();
        header.cloneBase(this);
        if (parsed) {
            header.sequenceNumber = this.sequenceNumber;
        }
        return header;
    }

    protected HeaderParser getParser() {
        return parser;
    }

    protected String getValueAsString() {
        return Integer.toString(sequenceNumber);
    }

    /**
     * Sets the sequence number value of the RSeqHeader of the provisional
     * response. The sequence number MUST be expressible as a 32-bit unsigned
     * integer and MUST be less than 2**31.
     *
     * @param sequenceNumber the new Sequence number of this RSeqHeader
     * @throws javax.sip.InvalidArgumentException
     *          if supplied value is less than zero.
     */
    public void setSequenceNumber(int sequenceNumber) throws InvalidArgumentException {
        parse();
        this.sequenceNumber = sequenceNumber;
        invalidateHeaderData();
    }

    /**
     * Gets the sequence number of this RSeqHeader.
     *
     * @return the integer value of the Sequence number of the RSeqHeader
     */
    public int getSequenceNumber() {
        parse();
        return this.sequenceNumber;
    }
}
/*
 * $Log$
 */